package cn.kgc.service.impl;

import cn.kgc.constant.MessageInfoType;
import cn.kgc.entity.MessageInfo;
import cn.kgc.mapper.MessageInfoMapper;
import cn.kgc.service.MessageInfoService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author YC
 */
@Slf4j
@Service("messageInfoService")
public class MessageInfoServiceImpl extends ServiceImpl<MessageInfoMapper, MessageInfo> implements MessageInfoService {

    @Override
    public MessageInfo getTransMessage(String id) {
        return baseMapper.selectById(id);
    }

    @Override
    public MessageInfo messageSendReady(String exchange, String routingKey, String body, String serviceName, long delayTime) {
        return messageSendReturn(exchange, routingKey, body, 1, serviceName, delayTime);
    }

    @Override
    public void messageSendSuccess(String id) {
        baseMapper.update(null, new LambdaUpdateWrapper<MessageInfo>()
                .eq(MessageInfo::getId, id).set(MessageInfo::getStatus, MessageInfoType.RECEIVE.getType()));
    }

    @Override
    public void messageDelete(String id) {
        baseMapper.deleteById(id);
    }

    @Override
    public MessageInfo messageSendReturn(String exchange, String routingKey, String body, int sequence, String serviceName, long delayTime) {
        MessageInfo messageInfo = MessageInfo.builder()
                .exchange(exchange)
                .routingKey(routingKey)
                .payload(body)
                .sequence(sequence)
                .status(MessageInfoType.SEND.getType())
                .service(serviceName)
                .delayTime(delayTime).build();
        baseMapper.insert(messageInfo);
        return messageInfo;
    }

    @Override
    public List<MessageInfo> listReadyMessage() {
        return baseMapper.selectList(new LambdaQueryWrapper<MessageInfo>()
                .eq(MessageInfo::getStatus, MessageInfoType.SEND.getType()));
    }

    @Override
    public void messageResend(String id) {
        baseMapper.update(null, new LambdaUpdateWrapper<MessageInfo>()
                .eq(MessageInfo::getId, id).setSql("sequence = sequence + 1"));
    }

    @Override
    public void messageMaxDead(String id) {
        baseMapper.update(null, new LambdaUpdateWrapper<MessageInfo>()
                .eq(MessageInfo::getId, id).set(MessageInfo::getStatus, "SENDER:" + MessageInfoType.DEAD.getType()));
    }

    @Override
    public void messageReceiveDead(String id) {
        baseMapper.update(null, new LambdaUpdateWrapper<MessageInfo>()
                .eq(MessageInfo::getId, id).set(MessageInfo::getStatus, "RECEIVE" + MessageInfoType.DEAD.getType()));
    }

    @Override
    public MessageInfo messageReceiveReady(String id, String exchange, String routingKey, String queue, String body, long delayTime) {
        // 根据ID判断数据库中是否有此消息（是否第一次消费）
        MessageInfo messageInfo = baseMapper.selectById(id);
        if (messageInfo == null) {
            // 如果是第一次消费，数据库没有此消息，保存到数据库
            messageInfo = MessageInfo.builder()
                    .id(id).exchange(exchange).routingKey(routingKey).queue(queue).payload(body).delayTime(delayTime)
                    .sequence(1).status(MessageInfoType.RECEIVE.getType()).build();
            baseMapper.insert(messageInfo);
        } else {
            // 如果消息存在，消费次数+1
            messageResend(id);
        }
        return messageInfo;
    }

    @Override
    public void messageReceiveSuccess(String id) {
        baseMapper.deleteById(id);
    }
}
